<?php
namespace com\rs\dns\service;

use com\rs\dns\constant\InstallConstant;
use com\rs\dns\controller\install\InstallForm;
use com\rs\dns\exception\BaException;
use com\rs\dns\repository\bean\UserListBean;
use com\rs\dns\repository\ConfigRepository;
use com\rs\dns\repository\HostCheckRepository;
use com\rs\dns\repository\IpTableV6Repository;
use com\rs\dns\repository\NetRepository;
use com\rs\dns\repository\RrRepository;
use com\rs\dns\repository\SoaRepository;
use com\rs\dns\repository\TokenRepository;
use com\rs\dns\repository\UrlRepository;
use com\rs\dns\repository\UserListRepository;
use com\rs\dns\utils\EncryptUtils;
use restphp\exception\RestException;
use restphp\i18n\RestLangUtils;
use restphp\utils\RestClassUtils;

/**
 * Class InstallDbService
 * @package com\rs\dns\service
 */
final class InstallDbService {
    /**
     * 执行.
     * @param InstallForm $installForm
     * @throws BaException
     * @throws RestException
     */
    public static function execute($installForm) {
        self::_tableConfig();
        self::_tableHostCheck();
        self::_tableIpTable();
        self::_tableIpTableV6();
        self::_tableNet();
        self::_tableRR();
        self::_tableSoa();
        self::_tableStopDomain();
        self::_tableStopIp();
        self::_tableToken();
        self::_tableUrl();
        self::_tableUserList();
        self::_initUser($installForm);
    }

    /**
     * @param string $table
     * @param string $message
     * @return string
     */
    private static function _buildError($table, $message) {
        $message = RestLangUtils::replace('[' . InstallConstant::INSTALL_ERROR_ON_TABLE . ']');
        $message = sprintf($message, $table, $message);
        return $message;
    }

    /**
     * 创建表config.
     * @throws RestException
     */
    private static function _tableConfig() {
        $sql = 'CREATE TABLE [dbo].[config] (
[id] int NOT NULL IDENTITY(1,1) ,
[configCode] varchar(100) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[configValue] varchar(255) COLLATE Chinese_PRC_CI_AS NULL 
)
ON [PRIMARY]';
        $configRepository = new ConfigRepository();
        $configRepository->pUpdateDB()->execute($sql);
        $sql2 = 'CREATE INDEX [idx_config_configCode_1] ON [dbo].[config]
([configCode] ASC) 
ON [PRIMARY]';
        $configRepository->pUpdateDB()->execute($sql2);
    }

    /**
     * 创建表hostcheck.
     * @throws BaException
     */
    private static function _tableHostCheck() {
        $sql = 'CREATE TABLE [dbo].[hostcheck](
	[IP] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[port] [int] NOT NULL,
	[weight] [int] NULL,
	[status] [varchar](5) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_hostcheck] PRIMARY KEY CLUSTERED 
(
	[IP] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]';
        $hostRepository = new HostCheckRepository();
        try {
            $hostRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('hostcheck', $e->getMessage()));
        }
    }

    /**
     * 创建表iptable.
     * @throws BaException
     */
    private static function _tableIpTable() {
        $sql = 'CREATE TABLE [dbo].[iptable](
	[id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[ip] [varchar](15) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[mask] [int] NOT NULL,
	[netid] [int] NOT NULL,
	[remark] [text] COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_iptable] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]';
        $ipTableRepository = new IpTableV6Repository();
        try {
            $ipTableRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('iptable', $e->getMessage()));
        }
    }

    /**
     * 创建表iptablev6.
     * @throws BaException
     */
    private static function _tableIpTableV6() {
        $sql = 'CREATE TABLE [dbo].[iptablev6](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[ip] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[mask] [varchar](5) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[netid] [int] NOT NULL,
	[remark] [text] COLLATE Chinese_PRC_CI_AS NULL,
	[ipStart1] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipStart1]  DEFAULT ((0)),
	[ipStart2] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipStart2]  DEFAULT ((0)),
	[ipStart3] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipStart3]  DEFAULT ((0)),
	[ipStart4] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipStart4]  DEFAULT ((0)),
	[ipEnd1] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipEnd1]  DEFAULT ((0)),
	[ipEnd2] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipEnd2]  DEFAULT ((0)),
	[ipEnd3] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipEnd3]  DEFAULT ((0)),
	[ipEnd4] [int] NOT NULL CONSTRAINT [DF_iptablev6_ipEnd4]  DEFAULT ((0)),
	[isChange] [tinyint] NOT NULL CONSTRAINT [DF_iptablev6_isChange]  DEFAULT ((1))
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]';
        $ipTableV6Repository = new IpTableV6Repository();
        try {
            $ipTableV6Repository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('iptablev6', $e->getMessage()));
        }
    }

    /**
     * 创建表net。
     * @throws BaException
     */
    private static function _tableNet() {
        $sql = 'CREATE TABLE [dbo].[net](
	[id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[netname] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[remark] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[aux] [int] NOT NULL DEFAULT ((0)),
 CONSTRAINT [PK_net] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]';
        $netRepository = new NetRepository();
        try {
            $netRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('net', $e->getMessage()));
        }
    }

    /**
     * 创建表rr.
     * @throws BaException
     */
    private static function _tableRR() {
        $sql = 'CREATE TABLE [dbo].[RR](
	[id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[zone] [int] NOT NULL,
	[name] [varchar](64) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[type] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[data] [varchar](255) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[aux] [int] NOT NULL,
	[ttl] [int] NOT NULL,
	[netid] [int] NOT NULL,
	[balance] [int] NOT NULL DEFAULT ((0)),
 CONSTRAINT [PK_RR2] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]';
        $rrRepository = new RrRepository();
        try {
            $rrRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('rr', $e->getMessage()));
        }
    }

    /**
     * 创建表SOA.
     * @throws BaException
     */
    private static function _tableSoa() {
        $sql = 'CREATE TABLE [dbo].[SOA](
	[id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[origin] [varchar](255) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[ns] [varchar](255) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[mbox] [varchar](255) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[serial] [int] NOT NULL,
	[refresh] [int] NOT NULL,
	[retry] [int] NOT NULL,
	[expire] [int] NOT NULL,
	[minimum] [int] NOT NULL,
	[ttl] [int] NOT NULL,
	[serial_t] [int] NULL,
	[username] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[yn] [varchar](5) COLLATE Chinese_PRC_CI_AS NULL,
	[topdate] [datetime] NULL,
	[enddate] [datetime] NULL,
	[password] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_SOA2] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]';
        $soaRepository = new SoaRepository();
        try {
            $soaRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('soa', $e->getMessage()));
        }
    }

    /**
     * 创建表：stopdomain.
     * @throws BaException
     */
    private static function _tableStopDomain() {
        $sql = 'CREATE TABLE [dbo].[stopdomain](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[stopdomain] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL,
	[dnsip] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL,
	[num] [int] NULL DEFAULT ((0)),
	[stoptime] [datetime] NULL
) ON [PRIMARY]';
        $soaRepository = new SoaRepository();
        try {
            $soaRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('stopdomain', $e->getMessage()));
        }
    }

    /**
     * 创建表stopip.
     * @throws BaException
     */
    private static function _tableStopIp() {
        $sql = 'CREATE TABLE [dbo].[stopip](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[stopip] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL,
	[dnsip] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL,
	[num] [int] NULL DEFAULT ((0)),
	[stoptime] [datetime] NULL
) ON [PRIMARY]';
        $soaRepository = new SoaRepository();
        try {
            $soaRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('stopip', $e->getMessage()));
        }
    }

    /**
     * 创建表token.
     * @throws RestException
     */
    private static function _tableToken() {
        $sql = 'CREATE TABLE [dbo].[token] (
[id] int NOT NULL IDENTITY(1,1) ,
[token] varchar(100) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[expireAt] datetime NOT NULL ,
[userId] int NOT NULL 
)
ON [PRIMARY]';
        $tokenRepository = new TokenRepository();
        $tokenRepository->pUpdateDB()->execute($sql);
        $sql2 = 'CREATE INDEX [idx_token_token_1] ON [dbo].[token]
([token] ASC) 
ON [PRIMARY]';
        $tokenRepository->pUpdateDB()->execute($sql2);
    }

    /**
     * 创建表URL.
     * @throws BaException
     */
    private static function _tableUrl() {
        $sql = 'CREATE TABLE [dbo].[URL](
	[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[domain] [varchar](100) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[URL] [varchar](250) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[URLtype] [varchar](10) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[netid] [int] NOT NULL,
	[verify] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[zone] int NOT NULL DEFAULT ((0)) ,
	[title] varchar(50) COLLATE Chinese_PRC_CI_AS NULL ,
 CONSTRAINT [PK_URL] PRIMARY KEY CLUSTERED 
(
	[domain] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]';
        $urlRepository = new UrlRepository();
        try {
            $urlRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('URL', $e->getMessage()));
        }
    }

    /**
     * 创建表userlist.
     * @throws BaException
     */
    private static function _tableUserList() {
        $sql = 'CREATE TABLE [dbo].[userlist](
	[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[username] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[password] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[realname] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
	[tel] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[address] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[postcode] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[email] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[msn] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[icq] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[isadmin] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[soanum] [int] NULL,
	[rrnum] [int] NULL,
	[verify] [varchar](5) COLLATE Chinese_PRC_CI_AS NULL,
	[regtime] [datetime] NULL,
 CONSTRAINT [PK_userlist] PRIMARY KEY CLUSTERED 
(
	[username] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]';
        $userRepository = new UserListRepository();
        try {
            $userRepository->pUpdateDB()->execute($sql);
        } catch (RestException $e) {
            throw new BaException(self::_buildError('userlist', $e->getMessage()));
        }
    }

    /**
     * 初始化用户.
     * @param InstallForm $installForm .
     */
    public static function _initUser($installForm) {
        $password = EncryptUtils::encodePassword($installForm->getManagePassword());
        $userBean = new UserListBean();
        $userBean->setUsername($installForm->getManageUsername());
        $userBean->setPassword($password);
        $userBean->setRealname('管理员');
        $userBean->setTel('13800000000');
        $userBean->setAddress('福建省福州市');
        $userBean->setPostcode('350002');
        $userBean->setEmail('info@fzrskj.com');
        $userBean->setMsn('info@fzrskj.com');
        $userBean->setIcq('779203660');
        $userBean->setIsadmin('Y');
        $userBean->setSoanum(5);
        $userBean->setRrnum(20);
        $userBean->setVerify('Y');
        $userBean->setRegtime(date('Y-m-d H:i:s'));
        $userRepository = new UserListRepository();
        $arrData = RestClassUtils::beanToArr($userBean);
        $userRepository->insert($arrData);
    }
}